package com.github.wxiaoqi.security.auth.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.share.distribution.entity.DisMemberInfo;
import com.codingapi.tx.annotation.TxTransaction;
import com.github.wxiaoqi.security.auth.bean.ClientInfo;
import com.github.wxiaoqi.security.auth.entity.AuthClientEntity;
import com.github.wxiaoqi.security.auth.feign.IUserService;
import com.github.wxiaoqi.security.auth.feign.ServiceDistributionFeign;
import com.github.wxiaoqi.security.auth.mapper.ClientMapper;
import com.github.wxiaoqi.security.auth.service.AuthClientService;
import com.github.wxiaoqi.security.auth.util.client.ClientTokenUtil;
import com.github.wxiaoqi.security.common.exception.auth.ClientInvalidException;
import com.github.wxiaoqi.security.common.util.UUIDUtils;

/**
 * Created by ace on 2017/9/10.
 */
@Service
public class DBAuthClientService implements AuthClientService {
    @Autowired
    private ClientMapper clientMapper;
    @Autowired
    private ClientTokenUtil clientTokenUtil;
    @Autowired
    private DiscoveryClient discovery;
    private ApplicationContext context;
    
    @Autowired
    private IUserService iUserService;
    
    @Autowired
    private ServiceDistributionFeign serviceDistributionFeign;

    @Autowired
    public DBAuthClientService(ApplicationContext context) {
        this.context = context;
    }

    @Override
    public String apply(String clientId, String secret) throws Exception {
        AuthClientEntity client = getClient(clientId, secret);
        return clientTokenUtil.generateToken(new ClientInfo(client.getCode(),client.getName(),client.getId().toString()));
    }

    private AuthClientEntity getClient(String clientId, String secret) {
        AuthClientEntity client = new AuthClientEntity();
        client.setCode(clientId);
        client = clientMapper.selectOne(client);
        if(client==null||!client.getSecret().equals(secret)){
            throw new ClientInvalidException("Client not found or Client secret is error!");
        }
        return client;
    }

    @Override
    public void validate(String clientId, String secret) throws Exception {
        AuthClientEntity client = new AuthClientEntity();
        client.setCode(clientId);
        client = clientMapper.selectOne(client);
        if(client==null||!client.getSecret().equals(secret)){
            throw new ClientInvalidException("Client not found or Client secret is error!");
        }
    }

    @Override
    public List<String> getAllowedClient(String clientId, String secret) {
        AuthClientEntity info = this.getClient(clientId, secret);
        List<String> clients = clientMapper.selectAllowedClient(info.getId() + "");
        if(clients==null) {
            new ArrayList<String>();
        }
        return clients;
    }

    @Override
    public List<String> getAllowedClient(String serviceId) {
        AuthClientEntity info = getClient(serviceId);
        List<String> clients = clientMapper.selectAllowedClient(info.getId() + "");
        if(clients==null) {
            new ArrayList<String>();
        }
        return clients;
    }

    private AuthClientEntity getClient(String clientId) {
        AuthClientEntity client = new AuthClientEntity();
        client.setCode(clientId);
        client = clientMapper.selectOne(client);
        return client;
    }

    @Override
    @Scheduled(cron = "0 0/1 * * * ?")
    public void registryClient() {
        // 自动注册节点
        discovery.getServices().forEach((name) ->{
            AuthClientEntity client = new AuthClientEntity();
            client.setName(name);
            client.setCode(name);
            AuthClientEntity dbClient = clientMapper.selectOne(client);
            if(dbClient==null) {
                client.setSecret(UUIDUtils.generateShortUuid());
                clientMapper.insert(client);
            }
        });
    }
    
    @Override
    @TxTransaction
    public Integer insertClient(AuthClientEntity entity) {
    	Integer id = clientMapper.insert(entity);
    	return id;
    }
    

	@Override
	@TxTransaction(isStart=true)
    @Transactional
	public Integer testtransaction(AuthClientEntity entity) {
		//增加auth_client表
		Integer id = insertClient(entity);
		Map<String,String> userMap = new HashMap<>();
		DisMemberInfo memberInfoVo= new DisMemberInfo();
		memberInfoVo.setDisUserId("456");
		memberInfoVo.setDisPlatSuper("789");
		//增加dis_member_info表
		serviceDistributionFeign.add(memberInfoVo);
		//增加baseuser表
		iUserService.insertUser(userMap);
		int i = 5/0;
		System.out.println(i);
		return id;
	}
}
